<?php
namespace plugins\store\model\store_rbac;
use think\Model;
use think\Db;
use app\admin\model\RoleModel;
use app\admin\model\AuthAccessModel;
use app\admin\model\AdminMenuModel;
use plugins\store\Common;

class StoreRbacModel extends Model
{
    //获取商铺管理角色信息
    public static function getSpgjRole()
    {
        return RoleModel::where( 'remark' , 'LIKE' , '%THISROLEIS_SPGL%' )->find(); 
    }
    
    //获取商铺角色列表
    /**
    *$storeId 商铺id 
    */
    public static function getStoreRoleList( $storeId , $str='' )
    {
        $list = [];
        $spgl = self::getSpgjRole();
        if( !empty( $spgl ) ){
            $children = self::getSubRole( $spgl['id'] , $storeId , $str );
            if( $children ){
                $spgl[ 'spread' ] = true;
                $spgl[ 'title' ] = $spgl['name'].ifCallBack( $str , $spgl );
                $spgl [ 'children' ] = $children;
                $list [] = $spgl;
            }
        }
        return $list;
    }
    
    /**
    * 
    *获取子级角色
    * 
    **/
    private static function getSubRole( $parentId , $storeId , $str )
    {
        $roles = RoleModel::where( 'parent_id' , $parentId )->where( 'remark' , 'like' , 'S_'.$storeId )->select();
        foreach ( $roles as $key => $arr ){
            $tmp = self::getSubRole( $arr['id'] , $storeId , $str );
            $roles[$key][ 'spread' ] = true;
            if( $tmp ){
                $roles[$key]['title']       =   $roles[$key]['name'].ifCallBack( $str , $arr );
                $roles[$key]['children']    =   $tmp;
            }
        }
        return $roles;
    }
    
    /** 
     *获取基础角色授权信息
     **/
    public static function getBaseRbacInfo( $roleId )
    {
        $spglRole = self::getSpgjRole();
        //获取基础菜单
        $menu = (new AdminMenuModel())->getMenu();
        $baseRole = AuthAccessModel::where( 'role_id' , $spglRole->id )->select();
        
        //过滤没有授权的菜单
        $menu = self::glMenu( $menu , $baseRole );
        
        
        //获取当前用户已经被授权的菜单
        $alreadMenu = AuthAccessModel::where( 'role_id' , $roleId )->column('menu_id');
        
        //构建树形
        return self::createTree( $menu , $alreadMenu );
        
    }
    //过滤没有授权的菜单
    private static function glMenu( $menu , $baseRole )
    {
        $list = [];

        $menuId = array_column( $baseRole ->toArray(), 'menu_id' );
        foreach ( $menu as $key => $value ){
            if( in_array( $value[ 'id' ] , $menuId ) ){
                $list [] = $value;
            }
        }
        return $list;
    }
    
    //构建树形
    private static function createTree( $list , $alreadMenu , $parentId = 0 )
    {
        $tree = [];
        $tmp = $list;
        foreach ( $list as $key => $value ){
            unset( $tmp [ $key ] );
            if( $parentId == $value [ 'parent_id' ] ){
                $value[ 'title' ] = $value[ 'name' ];
                $value[ 'spread' ] = true;
                
                
                
                $children = self::createTree( $tmp , $alreadMenu , $value[ 'id' ] );
                if( !empty( $children ) ){
                    $value ['children'] = $children;
                }
                $value ['checked'] = ( in_array( $value[ 'id' ] , $alreadMenu ) && ( empty( $children ) ) ) ;
                $tree [] = $value;
            }
        }
        return $tree;
    }
    
    
    //保存授权菜单
    public static function saveRbac( $menuList , $roleId )
    {
        if( empty( $menuList )  && !empty( $roleId ) ){
            AuthAccessModel::where( 'role_id' , $roleId )->delete();
            return true;
        }
        $fn = function( $menuList , &$select = [] ) use ( &$fn )  {
            foreach ( $menuList as $key => $value ){
                $tmp = $value ;
                if(isset( $tmp [ 'children' ] ) ) unset( $tmp [ 'children' ] );
                $select[] = $tmp ;
                if( isset( $value [ 'children' ] ) && !empty( $value [ 'children' ] ) ){
                    $fn( $value [ 'children' ] , $select );
                }
            }
            return $select;
        };
        //获取已选择的菜单
        $fn( $menuList , $select );
        //获取当前角色已授权的菜单
        $selectMenuIds = array_column( $select, 'id');
        //需要删除的
        $delete = AuthAccessModel::where( 'role_id', $roleId )->where( 'menu_id' , 'NOT IN' , $selectMenuIds )->column( 'id' );
        if( !empty( $delete ) ){
            AuthAccessModel::destroy( $delete );
        }
        //需要添加的
        foreach ( $select as $arr ){
            $find = AuthAccessModel::where( 'role_id' , $roleId )->where( 'menu_id' , $arr[ 'id' ] )->find();
            if(  !$find ){
                AuthAccessModel::create([
                    'role_id' => $roleId,
                    'rule_name' => $arr['app'].'/'.$arr['controller'].'/'.$arr['action'],
                    'type' => 1,
                    'company' => 0,
                    'menu_id' => $arr['id'],
                    'access_versions_id'=>0,
                    'code'=>''
                ]);
            }
        }
    }
    
    
    /**
     * 刷新权限
     * 
     **/
    public static function refreshAuth()
    {
        $spglRole = self::getSpgjRole();
        $storeInfo = Common::getStoreInfo();
        //获取基础菜单
        $baseRoleMenuIds = AuthAccessModel::where( 'role_id' , $spglRole->id )->column( 'menu_id' );
        
        //获取当前店铺下所有角色id
        $subRoleIds = RoleModel::where( 'remark' , 'like' , "S_".$storeInfo->store_id )->column( 'id' );
        
        //获取当前店铺下所有角色已授权的菜单
         $subMenuIds = AuthAccessModel::where( 'role_id' , 'in' , $subRoleIds )->column( 'menu_id' );
         
 	    //获取多余的已授权菜单
	    /*
        $a=[1,2,10,15];
        $b=[ 1,2,3,4,5,6,7,8];
        dump( array_diff( $b ,$a ) );
        结果筛选出: 3 4 5 6 7 8 */
        //求差集
        $delete = array_diff( $subMenuIds , $baseRoleMenuIds ) ;
        
        if( !empty( $delete ) ){
            AuthAccessModel::where( 'role_id' , 'in' , $subRoleIds )->where( 'menu_id' , 'in' , $delete )->delete();
        }     
        
        return true;
    }
    
    
    
    
    
}